package studio.raptor.databus.client;


import studio.raptor.databus.ActiveMQConnectionFactory;

import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Session;

/**
 * 队列消息生产者，每个生产者只能发送消息到一个指定的主题
 * <p>
 *     默认配置如下:<br>
 *     发送时间默认不超时<br>
 *     failover尝试重连次数一直重连<br>
 *     failover两次重连之间最大时间为10s<br>
 *     开启事务性会话<br>
 *     使用自动ACK模式<br>
 * </p>
 */
public final class DatabusProducerBuilder {

    private String bizCenterKey;

    private String topic;
    /**
     * 发送操作的超时时间，此时间并不会因重连操作打断。-1表示不超时。
     */
    private int timeout = -1;
    /**
     * 两次重连之间最长时间间隔，10s.
     */
    private int maxReconnectDelay = 10000;

    /**
     * failover机制中的最大重连次数。-1表示一直重连。
     */
    private int maxReconnectAttempts = -1;
    /**
     * 客户端启动时最大重连次数，默认为5
     */
    private int startupMaxReconnectAttempts = 5;

    private String otherURLConfig = "";

    /**
     * 会话是否为事务性，生产者默认开启
     */
    private boolean transactedSession = true;

    /**
     * 消息ACK模式，默认值(1)为自动确认
     */
    private int acknowledgeMode = Session.AUTO_ACKNOWLEDGE ;

    private DatabusConfig config;

    public DatabusProducerBuilder(String bizCenterKey, String topic,DatabusConfig config) {
        this.bizCenterKey = bizCenterKey;
        this.topic = topic;
        this.config = config ;
    }

    public DatabusProducer create() throws JMSException {
        DatabusProducer producer = new DatabusProducer();

        // 配置连接工厂类
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
        connectionFactory.setUserName(config.getUserName());
        connectionFactory.setPassword(config.getPassword());
        String customizedBrokerURL = this.transform2URLConfig();
        connectionFactory.setBrokerURL(config.getBrokerURL()+"?"+customizedBrokerURL);

        // 配置生产者客户端中的连接、会话
        producer.setConnection(connectionFactory.createConnection());
        producer.getConnection().start();
        producer.setSession(producer.getConnection().createSession(this.isTransactedSession(),this.getAcknowledgeMode()));
        String virtualTopic = config.VIRTUAL_TOPIC_PRE+this.getTopic();
        Destination destination = producer.getSession().createTopic(virtualTopic);

        producer.setMessageProducer(producer.getSession().createProducer(destination));
        return producer ;
    }

    public String getBizCenterKey() {
        return bizCenterKey;
    }

    public void setBizCenterKey(String bizCenterKey) {
        this.bizCenterKey = bizCenterKey;
    }

    public String getTopic() {
        return topic;
    }

    public void setTopic(String topic) {
        this.topic = topic;
    }

    public int getTimeout() {
        return timeout;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    public int getMaxReconnectDelay() {
        return maxReconnectDelay;
    }

    public void setMaxReconnectDelay(int maxReconnectDelay) {
        this.maxReconnectDelay = maxReconnectDelay;
    }

    public int getMaxReconnectAttempts() {
        return maxReconnectAttempts;
    }

    public void setMaxReconnectAttempts(int maxReconnectAttempts) {
        this.maxReconnectAttempts = maxReconnectAttempts;
    }

    public String getOtherURLConfig() {
        return otherURLConfig;
    }

    public void setOtherURLConfig(String otherURLConfig) {
        this.otherURLConfig = otherURLConfig;
    }

    public boolean isTransactedSession() {
        return transactedSession;
    }

    public void setTransactedSession(boolean transactedSession) {
        this.transactedSession = transactedSession;
    }

    public int getAcknowledgeMode() {
        return acknowledgeMode;
    }

    public void setAcknowledgeMode(int acknowledgeMode) {
        this.acknowledgeMode = acknowledgeMode;
    }

    public int getStartupMaxReconnectAttempts() {
        return startupMaxReconnectAttempts;
    }

    /**
     * 设置客户端启动时尝试连接服务器的最大次数，默认为5
     * @param startupMaxReconnectAttempts 客户端启动时尝试连接服务器的最大次数
     */
    public void setStartupMaxReconnectAttempts(int startupMaxReconnectAttempts) {
        this.startupMaxReconnectAttempts = startupMaxReconnectAttempts;
    }

    /**
     * 将生产者客户端配置转换为URL参数
     * @return
     */
    public String transform2URLConfig(){
        StringBuilder brokerURLConfig = new StringBuilder();
        brokerURLConfig.append("maxReconnectDelay=" + this.getMaxReconnectDelay());
        brokerURLConfig.append("&maxReconnectAttempts=" + this.getMaxReconnectAttempts());
        brokerURLConfig.append(this.getOtherURLConfig());
        return brokerURLConfig.toString();
    }
}
